package cn.wolfcode.luowowo.comment.service.impl;

import cn.wolfcode.luowowo.article.service.IScenicDetailService;
import cn.wolfcode.luowowo.comment.domain.ScenicComment;
import cn.wolfcode.luowowo.comment.repository.ScenicCommentMongoRepository;
import cn.wolfcode.luowowo.comment.service.IScenicCommentService;
import cn.wolfcode.luowowo.comment.vo.SumResult;
import cn.wolfcode.luowowo.common.query.ScenicQueryObject;
import cn.wolfcode.luowowo.common.util.AjaxResult;
import cn.wolfcode.luowowo.common.util.Consts;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class ScenicCommentServiceImpl implements IScenicCommentService {

    @Autowired
    private ScenicCommentMongoRepository repository;
    @Autowired
    private MongoTemplate template;
    @Reference
    private IScenicDetailService scenicDetailService;

    public AjaxResult save(ScenicComment comment) {
        AjaxResult result = new AjaxResult();
        //新增评论
        comment.setCreateTime(new Date());
        ScenicComment newComment = repository.save(comment);
        //新增一条评论的时候, 评论总数+1
        scenicDetailService.updateSumById(comment.getScenicId(), Consts.INCREASE_NUM);
        return result;
    }

    public List solvePage(Pageable pageable, List list){
        int fromIndex = pageable.getPageSize()*pageable.getPageNumber();
        int toIndex = pageable.getPageSize()*(pageable.getPageNumber()+1);
        int totalElements = list.size();
        if(toIndex> totalElements) toIndex = totalElements;
        list = list.subList(fromIndex,toIndex);
        return list;
    }

    public Page<ScenicComment> query(ScenicQueryObject qo) {
        Page<ScenicComment> page = null;
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1,3,Sort.by(Sort.Direction.DESC,"createTime"));
        //高级查询
        Integer type = qo.getType();
        Long scenicId = qo.getScenicId();
        switch (type) {
            // 有图
            case 0:
                List<ScenicComment> plist = picture(scenicId);
                List resultList = solvePage(pageable, plist);
                page = new PageImpl<>(resultList,pageable, plist.size()); break;
            //好中差评
            case 1:
                int[] score = qo.getScore();
                List<ScenicComment> slist = byScore(score[0], score[1],scenicId);
                List rsList = solvePage(pageable, slist);
                page = new PageImpl<>(rsList,pageable,slist.size()); break;
            //内容提及
            case 2:
                String keyword = qo.getKeyword();
                List<ScenicComment> clist = byContent(keyword,scenicId);
                List rcList = solvePage(pageable, clist);
                page = new PageImpl<>(rcList,pageable,clist.size()); break;
            //金牌点评
            case 3:
                List<ScenicComment> tlist = thumupComment(scenicId);
                List rtList = solvePage(pageable, tlist);
                page = new PageImpl<>(rtList,pageable,tlist.size()); break;
            default:
                page = repository.findByScenicId(scenicId, pageable);
                break;
        }
        return page;
    }

    public SumResult getSumData(Long scenicId) {
        SumResult vo = new SumResult();
        //全部评论
        Long totalComment = repository.findByScenicId(scenicId, null).getTotalElements();
        vo.setTotalComment(totalComment);

        //有照片, 就是pics不为null
        vo.setPicture(picture(scenicId).size());

        //好评, 查询的是总体评价分数4分和五分的
        vo.setGood(byScore(4, 5,scenicId).size());
        // 中评
        vo.setNormal(byScore(2,3,scenicId).size());
        //差评
        vo.setBad(byScore(0,1,scenicId).size());

        // 标志性建筑
        vo.setFeature(byContent("标志性建筑",scenicId).size());
        // 人很多
        vo.setMostPeople(byContent("人很多",scenicId).size());
        // 值得去
        vo.setWorthToGo(byContent("值得去",scenicId).size());
        // 恐高
        vo.setHigh(byContent("恐高",scenicId).size());
        //交通方便
        vo.setGoodTrans(byContent("交通方便",scenicId).size());

        // 金牌点评 点赞数 > 50
        vo.setThumupReply(thumupComment(scenicId).size());

        return vo;
    }

    private List<ScenicComment> thumupComment(Long scenicId) {
        Query query = new Query();
        query = new Query();
        query.addCriteria(Criteria.where("thumbupnum").gt(50));
        query.addCriteria(Criteria.where("scenicId").is(scenicId));
        List<ScenicComment> list = template.find(query, ScenicComment.class, "scenic_comment");
        return list;
    }

    private List<ScenicComment> picture(Long scenicId) {
        Query q = new Query();
        q.addCriteria(new Criteria().orOperator(
                Criteria.where("pics").size(1),
                Criteria.where("pics").size(2),
                Criteria.where("pics").size(3)
        ));
        q.addCriteria(Criteria.where("scenicId").is(scenicId));
        List<ScenicComment> list = template.find(q, ScenicComment.class, "scenic_comment");
        return list;
    }

    private List<ScenicComment> byScore(int min, int max, Long scenicId) {
        Query query = new Query();
        query.addCriteria(new Criteria().andOperator(
                Criteria.where("overallScore").gte(min),
                Criteria.where("overallScore").lte(max)
        ));
        query.addCriteria(Criteria.where("scenicId").is(scenicId));
        List<ScenicComment> list = template.find(query, ScenicComment.class, "scenic_comment");
        return list;
    }

    private List<ScenicComment> byContent(String keyword,Long scenicId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("content").regex(".*"+keyword+".*"));
        query.addCriteria(Criteria.where("scenicId").is(scenicId));
        List<ScenicComment> list = template.find(query, ScenicComment.class, "scenic_comment");
        return list;
    }

    public AjaxResult thumbup(String commentId, Long userId) {
        AjaxResult result = new AjaxResult();
        try {
            // 1) 根据评论id获取评论对象
            Optional<ScenicComment> op = repository.findById(commentId);
            // 2) 获取当前这条评论的点赞集合 comment就是当前这条评论对象
            op.ifPresent(comment -> {
                List<Long> thumbuplist = comment.getThumbuplist();
                // 3) 判断集合里面有没有当前登录用户的id, 有就删除, 没有就添加
                if (thumbuplist.contains(userId)) {
                    //取消点赞
                    thumbuplist.remove(userId);
                }else{
                    //点赞评论
                    thumbuplist.add(userId);
                }
                comment.setThumbupnum(thumbuplist.size());
                //把这条评论更新到mongoDB数据库里面, 有文档id就是更新, 没有就是新增
                repository.save(comment);
            });
        }catch (Exception e){
            e.printStackTrace();
            result.mark("操作失败");
        }
        return result;
    }
}
